/*
** Copyright (c) 2001 PIXAR.  All rights reserved.  This program or
** documentation contains proprietary confidential information and trade
** secrets of PIXAR.  Reverse engineering of object code is prohibited.
** Use of copyright notice is precautionary and does not imply
** publication.
**
**                      RESTRICTED RIGHTS NOTICE
**
** Use, duplication, or disclosure by the Government is subject to the
** following restrictions:  For civilian agencies, subparagraphs (a) through
** (d) of the Commercial Computer Software--Restricted Rights clause at
** 52.227-19 of the FAR; and, for units of the Department of Defense, DoD
** Supplement to the FAR, clause 52.227-7013 (c)(1)(ii), Rights in
** Technical Data and Computer Software.
**
** Pixar
** 1200 Park Ave
** Emeryville, CA 94608
**
** ----------------------------------------------------------------------------
*/
/* code generated by slim 6.0, RAT 6.0 (Mar 11 2004 04:21:00) */
/* for kidd@localhost at: Sun Apr 17 16:28:16 FLE Daylight Time 2005 */

/* includes ---------------------------------*/
#include "pxslRayUtil.h"

/* defines ----------------------------------*/
#define SLIM_TYPEID_surface 0
#define SLIM_TYPEID_displacement 1
#define SLIM_TYPEID_volume 2
#define SLIM_TYPEID_light 3
#define SLIM_VERSION 600
#define SLIM_SHADERTYPE surface
#define SLIM_SHADERTYPEID SLIM_TYPEID_surface
#define SLIM_INSTANCETYPE shadingmodel
#define SLIM_INSTANCENAME Blinn

/* shader body ------------------------------*/
SLIM_SHADERTYPE
SLIM_INSTANCENAME (
)
{

/* static functions ----------------------*/

	   void
	   pxslBlinn(color SurfaceColor;
		   color SurfaceOpacity;
		   color ambientColor;
		   color Incandescence;
		   float diffuseCoeff;
		   float translucenceCoeff;
		   color specularColor;
		   float eccentricity;
		   float specularRollOff;
		   float reflectivity;
		   output color CI;
		   output color OI; )
	   {
	       color
	       getTranslucence( normal Ns; float c; )
	       {
		   color C = 0;
		   extern point P;
		   extern color Cl;
		   float nondiff;

		   if( c != 0 )
		   {
		       illuminance(P, Ns, PI)
		       {
			   if( 0 == lightsource("__nondiffuse", nondiff) )
			       nondiff = 0;
			   C += (1 - nondiff) * Cl;
		       }
		       C *= c;
 		   }
		   return C;
	       }
	       color
	       getBlinn( normal Ns;
		       float eccentricity, specularRollOff;
		       output color Cr; )
	       {
		   float E;
		   color C = 0;
		   vector H, Ln, V, Nn;
		   float NH, NH2, NHSQ, Dd, Gg, VN, VH, LN, Ff, tmp;
		   float nondiff, nonspec;
		   extern point P;
		   extern vector L, I;
		   extern color Cl;

		   if(eccentricity != 1)
 			E = 1 / (eccentricity * eccentricity - 1);
		   else
			E = -1e5;
		   Cr = 0;
		   V = normalize(-I);
		   VN = V.Ns;
		   illuminance(P, Ns, 1.57079632679)
		   {
		       if( 0 == lightsource("__nonspecular", nonspec) )
			   nonspec = 0;
		       if( nonspec < 1 )
		       {
			   Ln = normalize(L);
			   H = normalize(Ln+V);
			   NH = Ns.H;
			   NHSQ = NH*NH;
			   NH2 = NH * 2;
			   Dd = (E+1) / (NHSQ + E);
			   Dd *= Dd;
			   VH = V.H;
			   LN = Ln.Ns;
			   if( VN < LN )
			   {
			       if( VN * NH2 < VH )
				   Gg = NH2 / VH;
			       else
				   Gg = 1 / VN;
			   }
			   else
			   {
			       if( LN * NH2 < VH )
				   Gg = (LN * NH2) / (VH * VN);
			       else
				   Gg = 1 / VN;
			   }
			   /* poor man's Fresnel */
			   tmp = pow((1 - VH), 3);
			   Ff = tmp + (1 - tmp) * specularRollOff;
			   C += Cl * Dd * Gg * Ff;

			   /* now look for environment reflections.  These
			       are indicated by lights which are specular AND
			       nondiffuse */
			   if( 0 != lightsource("__nondiffuse", nondiff) )
			   {
			       Cr += (1 - nonspec) * nondiff * Ff * Cl;
			   }
		       }
		   }
		   return C;
	       }
	       extern normal N;
	       extern vector I;
	       normal Ns = pxslUtilShadingNormal(N);
	       vector R;
	       color Ia, Id, Itr, Is, Ir, Isr;
	       R = reflect(normalize(I), Ns);
	       Ia = ambientColor * ambient();
	       Id = diffuseCoeff*diffuse(Ns);
	       Itr = getTranslucence(Ns, translucenceCoeff);
	       Is = getBlinn(Ns, eccentricity, specularRollOff, Ir);
	       Ir = reflectivity * Ir;
	       Isr = specularColor * (Is + Ir);
	       OI = SurfaceOpacity;
	       CI = OI * (SurfaceColor * (Ia + Id) + Itr + Incandescence + Isr);
	   }
       

/* dynamic functions ------------------------*/

/* local variables --------------------------*/
  color tmp0;
  color tmp1;

/* main body --------------------------------*/
  pxslBlinn ( /* Blinn */
    color(0,.25,1), /* Surface Color */
    color(1,1,1), /* Opacity */
    color(1,1,1), /* Ambient Color */
    color(0,0,0), /* Incandescence */
    .8, /* Diffuse Coefficient */
    0, /* Translucence Coefficient */
    color(1,1,1), /* Specular Color */
    .5, /* Eccentricity */
    .1, /* Specular Rolloff */
    1, /* Reflectivity */
    tmp0, /* CI */ 
    tmp1  /* OI */ 
    );
  Ci = tmp0;
  Oi = tmp1;
}

